#include "helper.h"
#include  <vector>
#ifdef _WIN32
#include <tlhelp32.h>
#include <Windows.h>
#include <Wtsapi32.h>
extern DWORD m_dwFolderSize ;
#endif // _WIN32
#include "hlog.h"
//��������
std::string appName = "Linkdood";
namespace privacy_service
{
	enum ObjType {
		OBJ_TYPE_INIT = 0,
		OBJ_TYPE_APP,
		OBJ_TYPE_USER,
		OBJ_TYPE_GROUP,
		OBJ_TYPE_OTHER
	};
	enum EntType {
		ENT_TYPE_INIT = 0,
		ENT_TYPE_A,
		ENT_TYPE_B,
		ENT_TYPE_C,
		ENT_TYPE_OTHER
	};
	
inline EntType GetEntType(int64 EntID) {
		hlogd("GetEntType start");
		//����56λ�ȼ���java�е��޷������������>>>
		uint64 entSign = ((uint64)EntID >> 56);
		if (0 <= entSign && entSign < 31)//����ֽ�0~31
			return ENT_TYPE_A;
		else if (64 <= entSign && entSign < 71)//����ֽ�64~71
			return ENT_TYPE_B;
		else if (127 == entSign)
			return ENT_TYPE_C;//����ֽ�127
		else
			return ENT_TYPE_OTHER;//�������
		hlogd("GetEntType end");
	}

inline int64 GetObjectEntID(int64 targetID) {
	int64 entID = 0;
	EntType entType = ENT_TYPE_INIT;
	hlogd("GetObjectEntID start");
	//��ȡ��ҵ����
	entType = GetEntType(targetID);
	switch (entType) {
	case ENT_TYPE_A: {
		entID = ((uint64)targetID >> 24);//ǰ5���ֽ�Ϊ��ҵID
		break;
	}
	case ENT_TYPE_B: {
		entID = ((uint64)targetID >> 32) << 8;//ǰ4���ֽ�Ϊ��ҵID���֣�Ȼ��һ���ֽڣ�Ϊ��ҵID
		break;
	}
	case ENT_TYPE_C: {
		entID = ((uint64)targetID >> 40) << 16;//ǰ3���ֽ�Ϊ��ҵID���֣�Ȼ��2���ֽڣ�Ϊ��ҵID
		break;
	}
	}
	hlogd("GetObjectEntID end");
	return entID;
}

inline void GetObjetRange(int64 objectID, ObjType objType,
	int64 & begin_id, int64 & end_id) {
	hlogd("GetObjetRange start");
	EntType entType = GetEntType(objectID << 24);
	int64 begin = 0;
	int64 end = 0;
	int64 minAppId = 0x15F90;//90000
	int64 maxAppId = 0x1869F;//99999
	int64 maxUserId = 0x7FFFFF;//8388607
	int64 maxGroupId = 0xFFFFFF;//1677721
	hlogd("GetObjetRange ing");
	switch (entType) {
	case ENT_TYPE_A: {
		if (objType == OBJ_TYPE_APP) {
			begin = (objectID << 24) + minAppId;
			end = (objectID << 24) + maxAppId;
		}
		else if (objType == OBJ_TYPE_USER) {
			begin = (objectID << 24) + maxAppId + 1;
			end = (objectID << 24) + maxUserId;
		}
		else if (objType == OBJ_TYPE_GROUP) {
			begin = (objectID << 24) + maxUserId + 1;
			end = (objectID << 24) + maxGroupId;
		}
		break;
	}
	case ENT_TYPE_B: {
		if (objType == OBJ_TYPE_APP) {
			begin = ((objectID >> 8) << 32) + (minAppId << 8);
			end = ((objectID >> 8) << 32) + (maxAppId << 8);
		}
		else if (objType == OBJ_TYPE_USER) {
			begin = ((objectID >> 8) << 32) + (maxAppId << 8) + 1;
			end = ((objectID >> 8) << 32) + (maxUserId << 8);
		}
		else if (objType == OBJ_TYPE_GROUP) {
			begin = ((objectID >> 8) << 32) + (maxUserId << 8) + 1;
			end = ((objectID >> 8) << 32) + (maxGroupId << 8);
		}
		break;
	}
	case ENT_TYPE_C: {
		if (objType == OBJ_TYPE_APP) {
			begin = ((objectID >> 16) << 40) + (minAppId << 16);
			end = ((objectID >> 16) << 40) + (maxAppId << 16);
		}
		else if (objType == OBJ_TYPE_USER) {
			begin = ((objectID >> 16) << 40) + (maxAppId << 16) + 1;
			end = ((objectID >> 16) << 40) + (maxUserId << 16);
			//begin = 9151315548882010113;
			//end   = 9151316092084224000;
		}
		else if (objType == OBJ_TYPE_GROUP) {
			begin = ((objectID >> 16) << 40) + (maxUserId << 16) + 1;
			end = ((objectID >> 16) << 40) + (maxGroupId << 16);
		}
		break;
	}
	}
	hlogd("GetObjetRange end");
	begin_id = begin;
	end_id = end;
	return;
}

inline bool JudgeRange(int64 targetID, ObjType objType) {
	hlogd("JudgeRange start");
	bool inside = false;
	int64 entID = GetObjectEntID(targetID);
	int64 begin, end;
	GetObjetRange(entID, objType, begin, end);
	hlogd("JudgeRange ing");
	if (targetID >= begin && targetID <= end) {
		inside = true;
	}
	return inside;
	hlogd("JudgeRange end");
}

bool isUser(int64 targetID) {
		hlogd("user");
		return JudgeRange(targetID, OBJ_TYPE_USER);
	}

bool isGroup(int64 targetID) {
		hlogd("group");
		return JudgeRange(targetID, OBJ_TYPE_GROUP);
	}

bool isApp(int64 targetID) {
		hlogd("App");
		return JudgeRange(targetID, OBJ_TYPE_APP);
	}

int getProcessCount(std::string name, bool onlyJudgeRunning)
	{
#ifdef _WIN32
		hlogd("getProcessCount start");
		int count = 0;
		std::string str1("");
		DWORD pid = 0;//dword���������� һ��word2���ֽڴ�С
		HANDLE hSnapShot = NULL;//HANDLE�Ǿ�� ����ָ��
		PROCESSENTRY32 pInfo;//�ṹ��
		pInfo.dwSize = sizeof(pInfo);
		pid = GetCurrentProcessId();
		//CreateToolhelp32Snapshot���Ի�ȡϵͳ�������еĽ�����Ϣ�����̿��գ� ����1��ָ������ ����2��ָ������id
		hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
		//����ʧ�ܵ����
		if (INVALID_HANDLE_VALUE == hSnapShot) {
			goto _EXIT_;
		}
		//Process32First���̻�ȡ���� ��ȡ���̿��պ� ��õ�һ�����̾��
		if (Process32First(hSnapShot, &pInfo)) {
			std::vector<long>proIds;
			std::vector<long>parProIds;
			do
			{
				str1 = std::string(pInfo.szExeFile);
				if (str1 == name) {
					if (onlyJudgeRunning) {
						count = 1;
						goto _EXIT_;
					}
					proIds.push_back(pInfo.th32ProcessID);//�������������
					parProIds.push_back(pInfo.th32ParentProcessID);
				}
			} while (Process32Next(hSnapShot, &pInfo));
			for (auto proId : proIds) {
				std::vector<long>::iterator it;
				it = find(parProIds.begin(), parProIds.end(), proId);
				if (it != parProIds.end()) {
					++count;
				}
			}
		}
		CloseHandle(hSnapShot);
	_EXIT_:
		return count;
		hlogd("getProcessCount end");
#endif // _WIN32
	}

const std::wstring s2ws(const std::string& s)
{
	std::locale old_loc = std::locale::global(std::locale(""));
	const char* src_str = s.c_str();
	const size_t buffer_size = s.size() + 1;
	wchar_t* dst_wstr = new wchar_t[buffer_size];
	wmemset(dst_wstr, 0, buffer_size);
	mbstowcs(dst_wstr, src_str, buffer_size);
	std::wstring result = dst_wstr;
	delete[]dst_wstr;
	std::locale::global(old_loc);
	return result;
}

void bigDataControl(std::string path, std::string param)
{
#ifdef _WIN32
	hlogd("bigDataControl start");
	if (param == "start") { //����bigData
		if ( getProcessCount("BigData.exe", true) == 0) { //��ʱû����ҵ��������,����������ҵ����
			ShellExecute(NULL, ("runas"), path.c_str(), param.c_str(), NULL, SW_NORMAL);//��һ���ļ�
		}
	}
	else {  //�ر�bigData
		if ( getProcessCount("Linkdood.exe", false) == 1) {  //��ʱֻ��һ����������,�����˳���ҵ����
			ShellExecute(NULL, ("runas"), path.c_str(), param.c_str(), NULL, SW_NORMAL);
		}
	}
	hlogd("bigDataControl end");
#endif
}

std::string getRegValue()
{
	std::string strValue("");//���ù��캯��
#ifdef _WIN32
	hlogd("string getRegValue start");
	HKEY hKey = HKEY_CURRENT_USER;
	HKEY hKeyResult = NULL;
	DWORD dwSize = 0;
	DWORD dwDataType = 0;
	std::string wstrUrl = REG_HKEY_PATH;
	std::string wstrKey = appName;
	//��ע���
	if (ERROR_SUCCESS == ::RegOpenKeyEx(hKey, wstrUrl.c_str(), 0, KEY_QUERY_VALUE, &hKeyResult))//��ָ����ע�����
	{
		//��ȡ����ĳ���dwSize������dwDataType
		//�һ�����ע�������������һ������ֵ�����ͺ�����
		::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, NULL, &dwSize);
		//�����ڴ��С
		TCHAR* lpValue = new TCHAR[dwSize];
		memset(lpValue, 0, dwSize * sizeof(TCHAR));
		if (ERROR_SUCCESS == ::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, (LPBYTE)lpValue, &dwSize))
		{
			strValue = std::string(lpValue);
			hlogd("strValue=%s", strValue.c_str());
		}
		delete[] lpValue;
	}
	::RegCloseKey(hKeyResult);//�ͷ�ָ��ע����
#endif // _WIN32
	return strValue;
	hlogd("string getRegValue end");
}
bool deleteRegValue()
{
#ifdef _WIN32
	hlogd("deleteRegValue start");
	HKEY hKey;
	LPCTSTR data_Set = REG_HKEY_PATH;
	if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, data_Set, 0, KEY_SET_VALUE, &hKey))
	{
		//ʹ��hKey������data_Set���KEY�����ֵ
		if (ERROR_SUCCESS == ::RegDeleteValue(hKey, appName.c_str()))
		{
			::RegCloseKey(hKey);
			return true;
		}
		::RegCloseKey(hKey);
	}
	hlogd("deleteRegValue end");
#elif __linux__
	int status = -1;
	status = system("rm $HOME/.config/autostart/Linkdood.desktop");
	hlogd("Client::deleteRegValue end status=%d", status);
	if (status == -1)
	{
		return false;
	}
	else {
		if (WIFEXITED(status))
		{
			if (0 == WEXITSTATUS(status))
			{
				return true;
			}
			else
			{
				hlogd("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
				return false;
			}
		}
		else
		{
			hlogd("exit status = [%d]\n", WEXITSTATUS(status));
			return false;
		}
	}

#elif __APPLE__
	int status = -1;
	status = system("rm $HOME/Library/LaunchAgents/com.vrv.linkdood.plist");
	if (status == -1)
	{
		return false;
	}
	else {
		if (WIFEXITED(status))
		{
			if (0 == WEXITSTATUS(status))
			{
				return true;
			}
			else
			{
				hlogd("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
				return false;
			}
		}
		else
		{
			hlogd("exit status = [%d]\n", WEXITSTATUS(status));
			return false;
		}
	}
#endif // _WIN32
	return false;
}

bool setRegValue()
{
#ifdef _WIN32
	hlogd("setRegValue start");
	HKEY hKey;
	char chpath[MAX_PATH];
	GetModuleFileName(NULL, chpath, sizeof(chpath));
	hlogd("GetModuleFileName failed(%d)", GetLastError());
	std::string name = chpath;
	LPBYTE m_name_Set = (LPBYTE)name.c_str();
	int length = name.length() + 1;
	LPCTSTR data_Set = REG_HKEY_PATH;
	if (ERROR_SUCCESS == ::RegOpenKeyEx(HKEY_CURRENT_USER, REG_HKEY_PATH, 0, KEY_SET_VALUE, &hKey))
	{
		if (ERROR_SUCCESS == ::RegSetValueEx(hKey, appName.c_str(), 0, REG_SZ, m_name_Set, length)) {
			::RegCloseKey(hKey);
			return true;
		}
		::RegCloseKey(hKey);
	}

#elif __linux__
	int status = -1;
	status = system("mkdir $HOME/.config/autostart; cp /usr/share/applications/Linkdood.desktop $HOME/.config/autostart/");
	hlogd("Client::setRegValue end status=%d", status);
	if (status == -1)
	{
		return false;
	}
	else {
		if (WIFEXITED(status))
		{
			if (0 == WEXITSTATUS(status))
			{
				return true;
			}
			else
			{
				hlogd("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
				return false;
			}
		}
		else
		{
			hlogd("exit status = [%d]\n", WEXITSTATUS(status));
			return false;
		}
	}

#elif __APPLE__
	int status = -1;
	status = system("mkdir $HOME/Library/LaunchAgents; cp /Applications/Linkdood.app/Contents/Resources/app/node_modules/vrv-static/lib/vimsdk/darwin/com.vrv.linkdood.plist $HOME/Library/LaunchAgents/com.vrv.linkdood.plist");
	if (status == -1)
	{
		return false;
	}
	else {
		if (WIFEXITED(status))
		{
			if (0 == WEXITSTATUS(status))
			{
				return true;
			}
			else
			{
				hlogd("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
				return false;
			}
		}
		else
		{
			hlogd("exit status = [%d]\n", WEXITSTATUS(status));
			return false;
		}
	}
#endif // _WIN32
	return false;
}

bool isSystemIdle()
{
#ifdef _WIN32
	hlogd("Client::isSystemIdle start");
	static __int64 last_idle = 0, last_kernel = 0, last_user = 0;
	__int64 idle, kernel, user;
	//GetSystemTimes��̬��ȡcpuռ���ʡ������� ����1������ʱ�� ����2���ں�ʱ�� ����3���û�ʱ��
	if (!GetSystemTimes((LPFILETIME)&idle, (LPFILETIME)&kernel, (LPFILETIME)&user))
	{
		OutputDebugString("fail to call GetSystemTimes/r/n");
		return false;
	}
	double rate = (double)(idle - last_idle) / (user - last_user + kernel - last_idle);
	hlogd("rate=%f", rate);
	last_idle = idle;
	last_kernel = kernel;
	last_user = user;
	if (rate >= 0.8)//����80%��ϵͳ���ڿ���״̬
	{
		return true;
	}
	return false;

#else
#define MAXLOAD 20 //Ҳ����˵�����ϵͳ���ز�����20%�������ǿ��е�
	hlogd("Client::isSystemIdle start");
	char buf[4];
	int f = open("/proc/loadavg", O_RDONLY);
	if (f<0)
	{
		//ptrTrace("fail to open file /proc/loadavg");
		return false;
	}
	if (read(f, buf, 4) != 4)
	{
		//ptrTrace("fail to read file /proc/loadavg");
		close(f);
		return false;
	}
	hlogd("Client::isSystemIdle end f=%d", f);
	close(f);
	return ((buf[0] == '0') && (atoi(buf + 2))<MAXLOAD);

#endif // _WIN32
}

#ifdef _WIN32
std::string WcharToChar(const wchar_t* wp, size_t m_encode)
{
	std::string str;
	int len = WideCharToMultiByte(m_encode, 0, wp, wcslen(wp), NULL, 0, NULL, NULL);
	char	*m_char = new char[len + 1];
	WideCharToMultiByte(m_encode, 0, wp, wcslen(wp), m_char, len, NULL, NULL);
	m_char[len] = '\0';
	str = m_char;
	delete[] m_char;
	return str;
}
#endif // _WIN32

std::string GBK_2_UTF8(std::string gbkStr)
{
#ifdef _WIN32
	std::string outUtf8 = "";
	int n = MultiByteToWideChar(CP_ACP, 0, gbkStr.c_str(), -1, NULL, 0);
	WCHAR *str1 = new WCHAR[n];
	MultiByteToWideChar(CP_ACP, 0, gbkStr.c_str(), -1, str1, n);
	n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
	char *str2 = new char[n];
	WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
	outUtf8 = str2;
	delete[]str1;
	str1 = NULL;
	delete[]str2;
	str2 = NULL;
	return outUtf8;
#else
	return gbkStr;
#endif
}

#ifdef _WIN32
void createProcessAndWait(std::string path, std::string param)
{
	hlogd("createProcessAndWait start");
	SHELLEXECUTEINFO ShExecInfo = { 0 };
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
	ShExecInfo.hwnd = NULL;
	ShExecInfo.lpVerb = NULL;
	ShExecInfo.lpFile = path.c_str();
	ShExecInfo.lpParameters = param.c_str();
	ShExecInfo.lpDirectory = NULL;
	ShExecInfo.nShow = SW_HIDE;//����״̬Ϊ����
	ShExecInfo.hInstApp = NULL;
	ShellExecuteEx(&ShExecInfo); //�����µĳ���
	WaitForSingleObject(ShExecInfo.hProcess, INFINITE);////�ȵ��ý��̽���
	CloseHandle(ShExecInfo.hProcess);
	hlogd("createProcessAndWait end");
}

std::string findWindowsAppUninstallPath(const char * dir)
{
	hlogd("findWindowsAppUninstallPath start");
	std::string uninstallPath("");
	intptr_t handle;
	_finddata_t findData;
	std::string dirPath = dir;
	dirPath.append("*.*");
	handle = _findfirst(dirPath.c_str(), &findData);    // ����Ŀ¼�еĵ�һ���ļ�
	if (handle == -1)
	{
		std::cout << "Failed to find first file!\n";
		return "";
	}
	do
	{
		if (findData.attrib & _A_SUBDIR
			&& strcmp(findData.name, ".") == 0
			&& strcmp(findData.name, "..") == 0
			)    // �Ƿ�����Ŀ¼���Ҳ�Ϊ"."��".."
		{
		}
		else
		{
			std::string name = findData.name;
			if (name.find("uninstall") != name.npos || name.find("Uninstall") != name.npos) {
				uninstallPath = dir;
				uninstallPath.append(name);
			}
		}
	} while (_findnext(handle, &findData) == 0);    // ����Ŀ¼�е���һ���ļ�
	_findclose(handle);    // �ر��������
	return uninstallPath;
	hlogd("findWindowsAppUninstallPath end");
}

std::string getWindowsAppPath(bool isInstallPath, std::string appName)
{
	hlogd("getWindowsAppPath start");
	std::string result("");
	result = searchWindowsAppPath(HKEY_LOCAL_MACHINE, isInstallPath, appName);
	if (result.empty())
	{
		result = searchWindowsAppPath(HKEY_CURRENT_USER, isInstallPath, appName);
	}
	return result;
	hlogd("getWindowsAppPath end");
}

std::string searchWindowsAppPath(HKEY key, bool isInstallPath, std::string appName)
{
	hlogd("searchWindowsAppPath start");
	std::string strValue("");
	HKEY hKey = key;
	HKEY  hKeyResult = NULL;
	DWORD dwSize = 0;
	DWORD dwDataType = 0;
	std::string wstrUrl = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
	wstrUrl.append(appName.c_str());
	std::string wstrKey = isInstallPath ? "" : "Path";
	//��ע���
	if (ERROR_SUCCESS == ::RegOpenKeyEx(hKey, wstrUrl.c_str(), 0, KEY_QUERY_VALUE, &hKeyResult))
	{
		// ��ȡ����ĳ���dwSize������dwDataType
	
		::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, NULL, &dwSize);
		//�����ڴ��С
		TCHAR* lpValue = new TCHAR[dwSize];
		memset(lpValue, 0, dwSize * sizeof(TCHAR));
		//��ȡע�����ָ���ļ�����Ӧ��ֵ
		if (ERROR_SUCCESS == ::RegQueryValueEx(hKeyResult, wstrKey.c_str(), 0, &dwDataType, (LPBYTE)lpValue, &dwSize))
		{
			strValue = std::string(lpValue);
		}
		delete[] lpValue;
	}
	//�ر�ע���
	::RegCloseKey(hKeyResult);
	if (strValue.empty() || isInstallPath) {
		return strValue;
	}
	strValue.append("\\");
	return  findWindowsAppUninstallPath(strValue.c_str());
	hlogd("searchWindowsAppPath end");
}

LONG GetSoftSign(std::string path, char * v_pszSign, int v_iBufSize)
{
	// ��������ת��
	hlogd("GetSoftSign start");
	wchar_t *v_pszFilePath;
	//�ַ��������ַ� ����ֵ��д�뻺�����Ŀ��ֽ���
	int len = MultiByteToWideChar(CP_ACP, 0, path.c_str(), strlen(path.c_str()), NULL, 0);
	v_pszFilePath = new wchar_t[len + 1];
	MultiByteToWideChar(CP_ACP, 0, path.c_str(), strlen(path.c_str()), v_pszFilePath, len);
	v_pszFilePath[len] = '\0';
	//�����жϲ����Ƿ���ȷ
	if (v_pszFilePath == NULL) return -1;
	HCERTSTORE		  hStore = NULL;
	HCRYPTMSG		  hMsg = NULL;
	PCCERT_CONTEXT    pCertContext = NULL;
	BOOL			  bResult;
	DWORD dwEncoding, dwContentType, dwFormatType;
	PCMSG_SIGNER_INFO pSignerInfo = NULL;
	PCMSG_SIGNER_INFO pCounterSignerInfo = NULL;
	DWORD			  dwSignerInfo;
	CERT_INFO		  CertInfo;
	SYSTEMTIME        st;
	LONG              lRet;
	DWORD             dwDataSize = 0;
	char   chTemp[MAX_PATH] = { 0 };
	do
	{
		//��ǩ���ļ��л�ȡ�洢���
		bResult = CryptQueryObject(
			CERT_QUERY_OBJECT_FILE,
			v_pszFilePath,
			CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
			CERT_QUERY_FORMAT_FLAG_BINARY,
			0,
			&dwEncoding,
			&dwContentType,
			&dwFormatType,
			&hStore,
			&hMsg,
			NULL
		);
		if (!bResult)
		{
			lRet = -1;
			break;
		}
		//��ȡǩ����Ϣ����Ļ�������С
		bResult = CryptMsgGetParam(
			hMsg,
			CMSG_SIGNER_INFO_PARAM,
			0,
			NULL,
			&dwSignerInfo
		);
		if (!bResult)
		{
			lRet = -1;
			break;
		}
		//���仺����
		//pSignerInfo = (PCMSG_SIGNER_INFO)GlobalAlloc(LPTR, dwSignerInfo);
		pSignerInfo = (PCMSG_SIGNER_INFO)malloc((dwSignerInfo));
		if (pSignerInfo == NULL)
		{
			lRet = -1;
			break;
		}
		//��ȡǩ����Ϣ
		bResult = CryptMsgGetParam(
			hMsg,
			CMSG_SIGNER_INFO_PARAM,
			0,
			pSignerInfo,
			&dwSignerInfo
		);
		if (!bResult)
		{
			lRet = -1;
			break;
		}

		CertInfo.Issuer = pSignerInfo->Issuer;
		CertInfo.SerialNumber = pSignerInfo->SerialNumber;
		pCertContext = CertFindCertificateInStore(
			hStore,
			PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
			0,
			CERT_FIND_SUBJECT_CERT,
			(PVOID)&CertInfo,
			NULL
		);
		if (pCertContext == NULL)
		{
			lRet = -1;
			break;
		}
		//��ȡ���ּ���
		//û�и�������������ô˵��ֻҪ��ȡ����Ҫ�ĳ���
		if (v_pszSign == NULL)
		{
			dwDataSize = CertGetNameString(
				pCertContext,
				CERT_NAME_SIMPLE_DISPLAY_TYPE,
				0,
				NULL,
				NULL,
				0
			);
			if (dwDataSize != 0)
			{
				lRet = dwDataSize;
			}
			else
			{
				lRet = -1;
			}

			break;
		}

		if (!(CertGetNameString(
			pCertContext,
			CERT_NAME_SIMPLE_DISPLAY_TYPE,
			0,
			NULL,
			v_pszSign,
			v_iBufSize
		)
			)
			)
		{
			lRet = -1;
			break;
		}

		lRet = 0;

	} while (FALSE);

	if (pSignerInfo != NULL)
	{
		free(pSignerInfo);
		//GlobalFree((HGLOBAL)pSignerInfo);
	}
	if (v_pszFilePath != NULL)
	{
		delete[] v_pszFilePath;
	}

	return lRet;
	hlogd("GetSoftSign end");
}

std::wstring SToWS(const std::string &s)
{
	size_t i;
	std::string curLocale = setlocale(LC_ALL, NULL);
	setlocale(LC_ALL, "chs");
	const char* _source = s.c_str();
	size_t _dsize = s.size() + 1;
	wchar_t* _dest = new wchar_t[_dsize];
	wmemset(_dest, 0x0, _dsize);
	mbstowcs_s(&i, _dest, _dsize, _source, _dsize);
	std::wstring result = _dest;
	delete[] _dest;
	setlocale(LC_ALL, curLocale.c_str());
	return result;
}

std::string Utf8ToGbk(const char *src_str)
{
#ifdef _WIN32
	int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0);
	wchar_t* wszGBK = new wchar_t[len + 1];
	memset(wszGBK, 0, len * 2 + 2);
	MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len);
	len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
	char* szGBK = new char[len + 1];
	memset(szGBK, 0, len + 1);
	WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
	std::string strTemp(szGBK);
	if (wszGBK) delete[] wszGBK;
	if (szGBK) delete[] szGBK;
	return strTemp;
#else
	return src_str;
#endif
}

BOOL GetDirSize(LPWSTR lpsPath)
{
#ifdef _WIN32
	HANDLE hFile;
	WIN32_FIND_DATAW WFD;
	WCHAR Path[MAX_PATH];
	LPWSTR lpcsPathParent;
	memset(Path, 0, MAX_PATH);
	lpcsPathParent = Path;
	wcscpy(lpcsPathParent, lpsPath);
	wcscat(lpcsPathParent, L"\\*");
	if ((hFile = FindFirstFileW(lpcsPathParent, &WFD)) == INVALID_HANDLE_VALUE)
		return FALSE;
	//��һ���ļ���Ϣ
	if (wcscmp(WFD.cFileName, L".") != 0 && wcscmp(WFD.cFileName, L"..") != 0)
	{
		if (WFD.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			WCHAR cPath[MAX_PATH];
			LPWSTR lpcsPath;
			memset(cPath, 0, MAX_PATH);
			lpcsPath = cPath;
			wcscpy(lpcsPath, lpsPath);
			wcscat(lpcsPath, L"\\");
			wcscat(lpcsPath, WFD.cFileName);
			GetDirSize(lpcsPath);
		}
		else
		{
			m_dwFolderSize += WFD.nFileSizeLow;
			if (m_dwFolderSize > 1024288000) {
				return FALSE;
			}
		}
	}
	while (hFile)
	{
		//����������Ϣ
		if (FindNextFileW(hFile, &WFD))
		{
			if (wcscmp(WFD.cFileName, L".") == 0 || wcscmp(WFD.cFileName, L"..") == 0)
				continue;
			if (WFD.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
			{
				WCHAR cPath[MAX_PATH];
				LPWSTR lpcsPath;
				memset(cPath, 0, MAX_PATH);
				lpcsPath = cPath;
				wcscpy(lpcsPath, lpsPath);
				wcscat(lpcsPath, L"\\");
				wcscat(lpcsPath, WFD.cFileName);
				GetDirSize(lpcsPath);
			}
			else
			{
				m_dwFolderSize += WFD.nFileSizeLow;
				if (m_dwFolderSize > 524288000) {
					return FALSE;
				}
			}
		}
		else
		{
			if (GetLastError() == ERROR_NO_MORE_FILES)
				break;
		}
	}
	FindClose(hFile);
#endif // _WIN32
	return TRUE;
}
#endif

int creatDir(char *pDir)
{
	hlogd("creatDir");
	int i = 0;
	int iRet = -1;
	int iLen;
	char* pszDir;
	if (NULL == pDir)
	{

		return 0;
	}
	//strdup ���ַ����������½�λ�ô� ����һ��ָ��
	
	pszDir = strdup(pDir);
	iLen = strlen(pszDir);
	hlogd("creatDir pszDir=%s",pszDir);
	//�����м�Ŀ¼
	for (i = 1; i < iLen; i++)
	{
		if (pszDir[i] == '\\' || pszDir[i] == '/')
		{
	
			pszDir[i] = '\0';
#ifdef _WIN32
			iRet = ACCESS(SToWS(pszDir).c_str(), 0);
#else
			iRet = ACCESS(pszDir, 0);

#endif // _WIN32
			if (iRet != 0)
			{
#ifdef _WIN32
				iRet = MKDIR(SToWS(pszDir).c_str());
#else
				iRet = MKDIR(pszDir);

#endif // _WIN32
				if (iRet != 0)
				{
					return -1;
				}
			}

			pszDir[i] = '/';//֧��linux������\����/
			
		}
	}

	free(pszDir);

	hlogd("Client::creatDir 1 iRet=%d ", iRet);
	return iRet;

}

int remove_Dir(const char* dirPath)
{
#ifdef _WIN32

	if (NULL == dirPath || ACCESS(SToWS(dirPath).c_str(), 0) != 0) {
		return 0;
	}
	if (!PathIsDirectoryW(SToWS(dirPath).c_str())) {
		DWORD  dwAttribute = GetFileAttributesW(SToWS(dirPath).c_str());
		if (FILE_ATTRIBUTE_NORMAL != (dwAttribute  &  FILE_ATTRIBUTE_NORMAL))
		{
			dwAttribute = FILE_ATTRIBUTE_NORMAL;
			SetFileAttributesW(SToWS(dirPath).c_str(), dwAttribute);
		}

		return _wremove(SToWS(dirPath).c_str());
	}
	std::vector<std::string> files;
	HANDLE hFile = 0;
	WIN32_FIND_DATA fileInfo;
	memset(&fileInfo, 0, sizeof(LPWIN32_FIND_DATA));

	std::string wsTemp(dirPath);
	std::string s = wsTemp.substr(wsTemp.length() - 2);
	if (std::string("\\") != s)
	{
		wsTemp.append(("\\"));
	}
	wsTemp.append(("*"));
	hFile = FindFirstFile(wsTemp.c_str(), &fileInfo);
	if (INVALID_HANDLE_VALUE != hFile) {
		do
		{
			std::string str = fileInfo.cFileName;
			//����ǵ�ǰĿ¼�������ϼ�Ŀ¼����ֱ�ӽ�����һ��ѭ��  
			if ("." == str || ".." == str)
			{
				continue;
			}
			files.push_back(fileInfo.cFileName);

		} while (FindNextFile(hFile, &fileInfo));

		FindClose(hFile);
	}
	for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i)
	{
		std::string sTemp(dirPath);
		sTemp.append(("\\")).append(*i);
		std::string srcName = sTemp.c_str();

		if (PathIsDirectoryW(SToWS(srcName.c_str()).c_str()))
		{
			int err = remove_Dir(srcName.c_str());
		}
		else {
			DWORD  dwAttribute = GetFileAttributesW(SToWS(srcName.c_str()).c_str());
			if (FILE_ATTRIBUTE_NORMAL != (dwAttribute  &  FILE_ATTRIBUTE_NORMAL))
			{
				dwAttribute = FILE_ATTRIBUTE_NORMAL;
				SetFileAttributesW(SToWS(srcName.c_str()).c_str(), dwAttribute);
			}

			int err = _wremove(SToWS(dirPath).c_str());
		}
	}

	int errdir = _wrmdir(SToWS(dirPath).c_str());
	return 0;
#else
	char cur_dir[] = ".";
	char up_dir[] = "..";
	char dir_name[256] = { 0 };
	DIR *dirp;
	struct dirent *dp;
	struct stat dir_stat;

	// �������ݽ�����Ŀ¼�����ڣ�ֱ�ӷ���
	if (0 != access(dirPath, F_OK)) {
		return 0;
	}
	// ��ȡĿ¼����ʧ�ܣ����ش���
	if (0 > lstat(dirPath, &dir_stat)) {
		return -1;
	}

	if (S_ISREG(dir_stat.st_mode)) {  // ��ͨ�ļ�ֱ��ɾ��
		std::string pathTemp = dirPath;
		chmod(pathTemp.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
		remove(dirPath);
		return 0;
	}
	strcat(dir_name, dirPath);
	strcat(dir_name, "/");
	if (S_ISDIR(dir_stat.st_mode)) {   // Ŀ¼�ļ����ݹ�ɾ��Ŀ¼������
		dirp = opendir(dirPath);
		while ((dp = readdir(dirp)) != NULL) {
			// ���� . �� ..
			if ((0 == strcmp(cur_dir, dp->d_name)) || (0 == strcmp(up_dir, dp->d_name))) {
				continue;
			}
			char all_name[256] = { 0 };
			strcat(all_name, dir_name);
			strcat(all_name, dp->d_name);
			remove_Dir(all_name);   // �ݹ����
		}
		closedir(dirp);
		rmdir(dirPath);     // ɾ����Ŀ¼
	}
	else {
		return -1;
	}
	return 0;
#endif
}

void ConvertUtf8ToGBK(std::string&amp, std::string strUtf8)
{
#ifdef _WIN32 
	//int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8.c_str(), -1, NULL, 0);
	//unsigned short * wszGBK = new unsigned short[len + 1];
	//memset(wszGBK, 0, len * 2 + 2);
	//MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)strUtf8.c_str(), -1, (LPWSTR)wszGBK, len);
	//len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
	//char *szGBK = new char[len + 1];
	//memset(szGBK, 0, len + 1);
	//WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wszGBK, -1, szGBK, len, NULL, NULL);
	////strUtf8 = szGBK; 
	//amp = szGBK;
	//delete[] szGBK;
	//delete[] wszGBK;
	WCHAR *strSrc;
	char *szRes;
	/// �����ʱ�����Ĵ�С
	int i = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, NULL, 0);
	strSrc = new WCHAR[i + 1];
	MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, strSrc, i);
	/// �����ʱ�����Ĵ�С
	i = WideCharToMultiByte(936, WC_COMPOSITECHECK | WC_DEFAULTCHAR, strSrc, -1, NULL, 0, NULL, NULL);
	szRes = new char[i + 1];
	int bud = 1;
	WideCharToMultiByte(936, WC_COMPOSITECHECK | WC_DEFAULTCHAR, strSrc, -1, szRes, i, " ", &bud);
	amp = szRes;
	delete[]strSrc;
	delete[]szRes;
#else
	char *inbuf = const_cast<char*>(strUtf8.c_str());
	size_t inlen = strlen(inbuf);
	size_t outlen = inlen * 4;
	char *outbuf = (char *)malloc(inlen * 4);
	bzero(outbuf, inlen * 4);
	char *in = inbuf;
	char *out = outbuf;
	iconv_t cd = iconv_open("GBK", "UTF-8");
	iconv(cd, &in, &inlen, &out, &outlen);
	iconv_close(cd);
	amp = outbuf;
#endif
}

}
